
function dateFormat(fmt, date) {
    let ret;
    const opt = {
        "Y+": date.getFullYear().toString(),        // 年
        "m+": (date.getMonth() + 1).toString(),     // 月
        "d+": date.getDate().toString(),            // 日
        "H+": date.getHours().toString(),           // 时
        "M+": date.getMinutes().toString(),         // 分
        "S+": date.getSeconds().toString()          // 秒
        // 有其他格式化字符需求可以继续添加，必须转化成字符串
    };
    for (let k in opt) {
        ret = new RegExp("(" + k + ")").exec(fmt);
        if (ret) {
            fmt = fmt.replace(ret[1], (ret[1].length === 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")));
        }
    }
    return fmt;
}

function toBase64(buffer) {
    let binary = ''
    let bytes = new Uint8Array(buffer)
    let len = bytes.byteLength
    for (let i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i])
    }
    return window.btoa(binary);
}

function to16BitPCM(input) {
    let dataLength = input.length * (16 / 8)
    let dataBuffer = new ArrayBuffer(dataLength)
    let dataView = new DataView(dataBuffer)
    let offset = 0
    for (let i = 0; i < input.length; i++, offset += 2) {
        let s = Math.max(-1, Math.min(1, input[i]))
        dataView.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true)
    }
    return dataView
}

function base64ToS16(base64AudioData) {
    const outputArray = new Uint8Array(base64AudioData.length)
    for (let i = 0; i < base64AudioData.length; ++i) {
        outputArray[i] = base64AudioData.charCodeAt(i)
    }
    return new Int16Array(new DataView(outputArray.buffer).buffer)
}

function transS16ToF32(input) {
    let tmpData = []
    for (let i = 0; i < input.length; i++) {
        let d = input[i] < 0 ? input[i] / 0x8000 : input[i] / 0x7fff
        tmpData.push(d)
    }
    return new Float32Array(tmpData)
}

function initWebSocket(context) {
    let path = location.host + location.pathname;
    if (path.substr(path.length - 1, 1) !== '/') {
        path = path.split('/').slice(0, -1).join('/') + '/';
    }

    const webSocket = new WebSocket('wss://' + path + 'websocket');
    webSocket.onopen = () => {
        if (context.onWebSocketOpen) {
            context.onWebSocketOpen();
        }
    };

    webSocket.onmessage = (evt) => {
        let data = JSON.parse(evt.data);
        const method = 'event' + data.event.charAt(0).toUpperCase() + data.event.slice(1);
        if (context[method]) {
            context[method](data.data);
        }
    };

    webSocket.onclose = () => {
        console.log("Connection closed.");
        if (context.onWebSocketClose) {
            context.onWebSocketClose();
        }
    };

    webSocket.emit = (event, data) => {
        webSocket.send(JSON.stringify({
            event: event,
            data: data,
        }));
    };

    return webSocket;
}

function guid() {
    return 'xxxxxxxx'.replace(/[xy]/g, function (c) {
        let r = Math.random() * 16 | 0,
            v = c === 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}
